import jsIcon from "../assets/fileicons/js.svg";
import tsIcon from "../assets/fileicons/ts.svg";
import cssIcon from "../assets/fileicons/css.svg";
import vueIcon from "../assets/fileicons/vue.svg";
import txtIcon from "../assets/fileicons/txt.svg";
import htmlIcon from "../assets/fileicons/html.svg";
import jsonIcon from "../assets/fileicons/json.svg";
import svgIcon from "../assets/fileicons/svg.svg";
import { IFileTreeItem } from "../interface/FileTree";
import unknownIcon from "../assets/fileicons/unknown.svg";
import { IKeyMap } from "../interface";

/**
 * 解析文件图标
 * @param fileName 文件名
 */
function getFileIcon(label: string) {
  const suffix = getFileSuffix(label);
  const iconsMap: IKeyMap<string, string> = {
    html: htmlIcon,
    txt: txtIcon,
    json: jsonIcon,
    css: cssIcon,
    js: jsIcon,
    ts: tsIcon,
    svg: svgIcon,
    vue: vueIcon,
  };
  if (iconsMap[suffix]) return iconsMap[suffix];
  return unknownIcon;
}

/**
 * 根据提供的 fileTree ID 解析当前路径
 * @param data fileTree 数据源
 * @param id 文件 ID
 * @param fullpath 是否返回完整路径 默认为 false
 *
 *    @example fullpath 为 true 时，返回 /src/index.js （/src/main）
 *    @example fullpath 为 false 时，返回 /src (/src)
 *
 * @returns {string}
 */
function getFilePath(
  data: IFileTreeItem[],
  id: string,
  fullpath: boolean = false,
  cpath: string[] = []
): string | "" {
  const path = findPath(data, id, fullpath, cpath);
  if (!path) return "";
  return "/" + path;
}
function findPath(
  data: IFileTreeItem[],
  id: string,
  fullpath: boolean = false,
  cpath: string[] = []
): string | undefined {
  for (const node of data) {
    const newPath = [...cpath, node.label];
    if (node.id === id) {
      /**
       * 这里要处理一个根路径问题
       * 每一个数据项 都拥有唯一的路径，不然会报错
       *  这里创建的每一项数据项，都会更新 id = path 操作
       *  请确保更新后的ID 保持与 path 一致，否则会报错
       *  /src
       *  /index.js
       *  /src/ttt.ts
       */
      if (fullpath) return newPath.join("/");
      else {
        /**
         * 如果是文件夹的话，任何场景下都需要返回后缀
         *  例如 id =‘/src’ ==> '/src'
         */
        if (node.type === "Folder") {
          return newPath.filter((i) => i).join("/");
        }
        return newPath.slice(0, -1).join("/");
      }
    }
    if (node.children && node.children.length > 0) {
      const foundPath = findPath(node.children, id, fullpath, newPath);
      if (foundPath) return foundPath;
    }
  }
}

/**
 * 获取唯一ID
 */
function getUniqueId() {
  return Math.random().toString(36).substring(2, 15) + Date.now();
}

/**
 * 进行数据处理 - 递归删除某一项 - 用于删除特定条件下的数据项，例如 isNew rename id=12
 * @param data 数据源
 * @param fun 删除条件
 */
function deleteItem(
  data: IFileTreeItem[],
  fun: (item: IFileTreeItem) => boolean
) {
  for (let i = 0; i < data.length; i++) {
    const item = data[i];
    if (fun(item)) {
      data.splice(i, 1);
      i--;
    } else if (item.children) {
      deleteItem(item.children, fun);
    }
  }
  return data;
}

/**
 * 进行数据处理 - 递归实现查找某一项数据项，并返回
 * @param data 数据源
 * @param fun 查找条件
 * @returns {IFileTreeItem|null} item 返回查找的数据项
 */
function findItem(
  data: IFileTreeItem[],
  fun: (item: IFileTreeItem) => boolean
): IFileTreeItem | null {
  for (const item of data) {
    if (fun(item)) {
      return item;
    }
    if (item.children && item.children.length > 0) {
      const foundItem = findItem(item.children, fun);
      if (foundItem) {
        return foundItem;
      }
    }
  }
  return null;
}

/**
 * 换肤实现
 */
export function setTheme(name: "dark" | "light") {
  const html = document.querySelector("html")!;
  html.setAttribute("data-theme", name);
}

/**
 * 解析文件后缀
 */
function getFileSuffix(filename: string) {
  if (!filename) return "";
  return filename.split(".").pop()!;
}

/**
 * 解析文件名
 *  /src/index.js ===> index.js
 */
function getFileName(path: string) {
  return path.split("/").pop()!;
}

export const Utils = {
  getFileIcon,
  getFilePath,
  getUniqueId,
  deleteItem,
  setTheme,
  findItem,
  getFileSuffix,
  getFileName,
};
